﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Data.SqlServerCe;
using System.Configuration;
using System.IO;

using System.Windows.Documents;
using System.Windows.Media.Effects;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows;
//using Gma.UserActivityMonitor;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Windows.Resources;
using System.Windows.Data;

namespace MercuryFE
{


    public static class ClientLib
    {

        [DllImport("user32.dll")]
        public static extern int ExitWindowsEx(int uFlags, int dwReason);

        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        public enum FontSizeType
        {
            Normal, Heading, Subheading
        };

        public static int getFontSize(Window win, FontSizeType fontSizeType)
        {
            // gets the font size to use in relation to the window height
            int fontsize = (int)((win.ActualHeight / 20) * 0.65);

            if (fontSizeType == FontSizeType.Heading)
            {
                fontsize = (int)(fontsize * 1.1);
            }

            return fontsize;
        }

        public static string getCurrentDir()
        {
            return AppDomain.CurrentDomain.BaseDirectory.ToString();
        }




        public static string getConnectionString()
        {
            string currentDir = getCurrentDir();

            string connectionString = "Data Source=" + currentDir + (!currentDir.EndsWith("\\") ? "\\" : "") + "LauncherDB.sdf; Max Database Size=512";

            return connectionString;

            // temporary fix....
            //return @"Data Source=C:\Documents and Settings\horvathm\My Documents\Visual Studio 2008\Projects\Launcher\bin\Debug\LauncherDB.sdf; Max Database Size=512";
        }

        public static bool truncateTable(SqlCeConnection conn, string tableName, string identityColumn, ref string error)
        {
            // no support for truncate in sql ce - delete and reset identity (if specified)
            string sql = "delete from " + tableName;
            using (SqlCeCommand ceComm = new SqlCeCommand(sql, conn)) { ceComm.ExecuteNonQuery(); }

            if (identityColumn != "")
            {
                sql = "alter table " + tableName + " alter column " + identityColumn + " identity (1,1);";
                using (SqlCeCommand ceComm = new SqlCeCommand(sql, conn))
                {
                    try
                    {
                        ceComm.ExecuteNonQuery();
                    }
                    catch (Exception e)
                    {
                        error = "Truncate table [" + tableName + "] : " + e.Message;
                        return false;
                    }
                }
            }
            return true;
        }


        public static string getConfig(string config)
        {
            string value = "";
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {

                    value = (from x in db.Configuration
                                 where x.Name == config
                                 select x.Value).SingleOrDefault().ToString();
                }
            }
            return value;
        }

        public static Dictionary<string,string> getConfigs(string category) {

            Dictionary<string, string> configs = new Dictionary<string, string>();
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {

                    configs = (from x in db.Configuration
                             where x.Category == category
                             select new { x.Name, x.Value }).ToDictionary(a=> a.Name, b => b.Value);
                }
            }
            return configs;
        }

        public static Image getImage(string fullName) {
            if (fullName == null || !File.Exists(fullName))
                return null;

            Image i = new Image();

            Uri uriSource = new Uri(fullName, UriKind.Absolute);
            i.Source = new BitmapImage(uriSource);
            return i;
        }

        public static Image getImageFromMedia(string name)
        {
            string currentDir = getCurrentDir();
            string imageName = currentDir + (!currentDir.EndsWith("\\") ? "\\" : "") + "Media\\" + name + ".png";
            return (getImage(imageName));
        }

        //public static Image getImageFromTheme(string name)
        //{
        //    string path = getConfig("Theme Path");

        //    path = path + (path.EndsWith("\\") ? "" : "\\") + name;

        //    return (getImage(path));
        //}

        public static void getControlFlags(ref bool useKeyboard, ref bool useMouse, ref bool useJoystick)
        {
            string prefix = "Enable", category = "Controls";

            useKeyboard = false;
            useMouse = false;
            useJoystick = false;

            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {
                    Dictionary<string, bool> controlFlags =
                                 (from x in db.Configuration
                                   where x.Category == category
                                   select new
                                   {
                                       key =  x.Name.Substring(prefix.Length)
                                       ,
                                       flag = (x.Value=="yes"?true:false)
                                   }).ToDictionary(a => a.key, b => b.flag);

                    foreach (KeyValuePair<string, bool> item in controlFlags)
                    {
                        switch (item.Key)
                        {
                            case "Mouse": useMouse = item.Value; break;
                            case "Keyboard": useKeyboard = item.Value; break;
                            case "Joystick": useJoystick = item.Value; break;

                        }

                    }
                }

            }
        }

        public static Dictionary<string, InputDeviceTypeAction> getGUIKeyMappings(InputDeviceType deviceType)
        {
            Dictionary<string, InputDeviceTypeAction> keyMappings = null;

            string category = "", suffix = "";

            if (deviceType == InputDeviceType.keyboard)
            {
                category = "Controls - Keyboard";
                suffix = "Key";
            }
            else if (deviceType == InputDeviceType.mouse)
            {
                category = "Controls - Mouse";
                suffix = "MouseButton";
            }
            else if (deviceType == InputDeviceType.joystick)
            {
                category = "Controls - Joystick";
                suffix = "JoyButton";
            }


            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {
                    keyMappings = (from x in db.Configuration
                                 where x.Category == category
                                 select new
                                 {
                                     x.Value
                                     ,
                                     actionType = Enum.Parse(typeof(InputDeviceTypeAction), x.Name.Substring(0,x.Name.Length-suffix.Length))
                                 }).ToDictionary(a => a.Value, b => (InputDeviceTypeAction)b.actionType); 
                }

            }
            return keyMappings;

            /*
             	
             */
        }

        public static Dictionary<string,string> getKeyMappings(int gameId) {
            // example field  {{"A"},{"Z"},{"B"},{null}}
            Dictionary<string, string> keyMappings = null;

            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {
                    int emulatorID = (from x in db.Game
                                    where x.GameID == gameId
                                    select x.EmulatorID).Single();
                    string rawKeyMappings = null;
                    // custom game
                    if (emulatorID == 0)
                    {
                        // get mappings from game record

                        rawKeyMappings = (from g in db.Game
                                            where g.GameID == gameId
                                            select g.KeyMappings).Single();
                    }
                    else
                    {
                        // grab from the emulator
                        rawKeyMappings = (from e in db.Emulator
                                            where e.EmulatorID == emulatorID
                                            select e.KeyMappings).Single();
                    }

                    if (rawKeyMappings != null && rawKeyMappings.Trim() != "")
                    {
                        keyMappings = StringToKeyMapping(rawKeyMappings);
                    }

                }
            }


            return keyMappings;

        }

        private static Dictionary<string, string> StringToKeyMapping(string value)
        {
            // COPIED STRAIGHT FROM LAUNCHERLIB IN CONFIG - MIGHT NEED TO HAVE THIS SOMEWHERE ELSE?
            if (value == null || value.Trim() == "")
                return null;

            if (!value.StartsWith("{{") || !value.EndsWith("}}"))
                return null;

            string temp = value.Substring(2, value.Length - 4); // ignore the two start and end brackets

            string[] aTemp = temp.Split(',');


            Dictionary<string, string> KeyMappings = new Dictionary<string, string>();
            for (int i = 0; i < aTemp.Length; i += 2)
            {
                string itemOne = aTemp[i].Trim(new char[] { '{', '\"', '}' });
                string itemTwo = aTemp[i + 1].Trim(new char[] { '{', '\"', '}' });

                if (itemTwo == "null")
                    itemTwo = null;
                KeyMappings.Add(itemOne, itemTwo);

            }

            return KeyMappings;
        }


        public static MenuLink getGameMenuLink(int gameId)
        {
            MenuLink gameLink = null;
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {
                    string host = getConfig("Theme Path"); // @"G:\RetroGaming\images"; //  
                    host = host + (!host.EndsWith("\\") ? "\\" : "");

                    gameLink = (from g in db.Game 
                                     join e in db.Emulator on g.EmulatorID equals e.EmulatorID
                                     join ep in db.EmulatorPath on g.SnapshotPathID equals ep.EmulatorPathID into image
                                     from results in image.DefaultIfEmpty()
                                     where g.GameID == gameId
                                     join np in db.MameNPlayers on g.MameRomID equals np.MameRomID into nplayers
                                     from results2 in nplayers.DefaultIfEmpty()
                                     select new MenuLink
                                     {
                                         Name = g.Name
                                         ,
                                         Description = g.Description
                                         ,
                                         Image = g.SnapshotFile != null ? results.Path + g.SnapshotSubPath + "\\" + g.SnapshotFile : host + "noimage.jpg"
                                         ,
                                         IsMenu = false
                                         ,
                                         Key = gameId
                                         ,
                                         ParentMenuID = -1
                                         ,
                                         LastPlayed = g.LastPlayed
                                         ,
                                         TotalTimePlayed = g.TotalTimePlayed
                                         ,
                                         NumberTimesPlayed = g.NumberTimesPlayed
                                         ,
                                         NPlayers = results2.NPlayers
                                         ,
                                         EmulatorImage = (e.ImageName == null || e.ImageName.Trim() == "" ? "" : host + e.ImageName)
                                         ,
                                         EmulatorName = e.Name
                                         ,
                                         IsMame = (e.IsMame == 1 ? true : false)
                                         ,
                                         HasImage = ((g.SnapshotFile == null || g.SnapshotFile == "") ? false : true)
                                         ,
                                         IsGame = true

                                     }).SingleOrDefault();
                }
            }
            return gameLink;
        }

        public static MenuLevel getMenuLevel(int menuId, bool isTextMenu)
        {
            // retrieve information for the specified menu (0 is top level)
            // this will also return child menus and games sitting underneath

            // if at top level (menu 0), then we only return child menus, since you can't store games
            // directly under the top
            MenuLevel menuLevel = new MenuLevel();

            List<MenuLink> menuLinks = new List<MenuLink>();
            List<string> menuPath = new List<string>();
            int parentMenuId = 0;
            string menuType = "standard";


            string host = getConfig("Theme Path"); // @"G:\RetroGaming\images"; //  
            host = host + (!host.EndsWith("\\") ? "\\" : "");

            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {


                    // build up the menu path...(breadcrumb bar?)
                    if (menuId != 0)
                    {
                        int currentMenuId = menuId;
                        bool firstIteration = true;
                        while (currentMenuId != 0)
                        {
                            var currentMenu = (from x in db.Menu
                                               where x.MenuID == currentMenuId
                                               select new
                                               {
                                                   Menu = x.Name
                                                   ,
                                                   ParentMenuId = (int)(x.ParentMenuID == null ? 0 : x.ParentMenuID)
                                                   ,
                                                   MenuType = x.MenuType
                                               }).Single();

                            if (firstIteration)
                            {
                                firstIteration = false;
                                parentMenuId = (currentMenu.ParentMenuId < 0 ? 0 : currentMenu.ParentMenuId);
                                menuType = currentMenu.MenuType;
                            }

                            menuPath.Add(currentMenu.Menu);
                            currentMenuId = currentMenu.ParentMenuId;

                        }
                    }
                    menuPath.Reverse();
                    menuLevel.Level = menuPath.Count;

                    // add all the menus first (for this menu)
                    List<MenuLink> childMenuLinks =
                                    (from x in db.Menu
                                     where  menuId == ((int)x.ParentMenuID == null ? 0 : (int)x.ParentMenuID)
                                     select new MenuLink
                                     {
                                         Name = (isTextMenu ?
                                         (x.MenuType == "music" ?  "< " + x.Name + " >" : "[ " +  x.Name + " ]" )
                                         : x.Name)
                                        ,
                                         Description = x.Description
                                        ,
                                         Image = host + ((x.ImageName == null || x.ImageName == "") ? "folder.png" : x.ImageName)
                                        ,
                                         IsMenu = true
                                        ,
                                         Key = x.MenuID
                                        ,
                                         ParentMenuID = (x.ParentMenuID == null || x.ParentMenuID < 0 ? 0 : (int)x.ParentMenuID)
                                         ,
                                         HasImage = ((x.ImageName == null || x.ImageName == "") ? false : true)
                                         ,
                                         SecuredLevel = (x.Password != null && x.Password.Trim() != "" ? true : false)
                                         ,
                                         SecuredPassword = (x.Password != null && x.Password.Trim() != "" ? x.Password : null)
                                         ,
                                         IsGame = true
                                         ,
                                         Video = null
                                     }).ToList();


                    menuLinks.AddRange(childMenuLinks);


                    // now any games
                    List<MenuLink> itemMenuLinks = null;
                    if (menuId != 0)
                    {
                        if (menuType == "standard")
                        {
                            itemMenuLinks = (from mc in db.MenuCollection
                                             join g in db.Game on mc.GameID equals g.GameID
                                             join e in db.Emulator on g.EmulatorID equals e.EmulatorID
                                             join ep in db.EmulatorPath on g.SnapshotPathID equals ep.EmulatorPathID into image
                                             from results in image.DefaultIfEmpty()
                                             where mc.MenuID == menuId
                                             join np in db.MameNPlayers on g.MameRomID equals np.MameRomID into nplayers
                                             from results2 in nplayers.DefaultIfEmpty()

                                             join ep2 in db.EmulatorPath on g.MoviePathID equals ep2.EmulatorPathID into video
                                             from results3 in video.DefaultIfEmpty()
                                             select new MenuLink
                                             {
                                                 Name = g.Name
                                                 ,
                                                 Description = g.Description
                                                 ,
                                                 Image = g.SnapshotFile != null ? results.Path + g.SnapshotSubPath + "\\" + g.SnapshotFile : host + "noimage.jpg"
                                                 ,
                                                 IsMenu = false
                                                 ,
                                                 Key = mc.GameID
                                                 ,
                                                 ParentMenuID = -1
                                                 ,
                                                 LastPlayed = g.LastPlayed
                                                 ,
                                                 TotalTimePlayed = g.TotalTimePlayed
                                                 ,
                                                 NumberTimesPlayed = g.NumberTimesPlayed
                                                 ,
                                                 NPlayers = results2.NPlayers
                                                 ,
                                                 EmulatorImage = (e.ImageName == null || e.ImageName.Trim() == "" ? "" : host + e.ImageName)
                                                 ,
                                                 EmulatorName = e.Name
                                                 ,
                                                 IsMame = (e.IsMame == 1 ? true : false)
                                                 ,
                                                 HasImage = ((g.SnapshotFile == null || g.SnapshotFile == "") ? false : true)
                                                 ,
                                                 IsGame = true
                                                 ,
                                                 Video = g.MovieFile != null ? results3.Path + g.MovieSubPath + "\\" + g.MovieFile : null

                                             }).ToList();
                        }
                        else if (menuType == "music") {
                            itemMenuLinks = (from mc in db.MenuCollection
                                             join c in db.JBCollection on mc.GameID equals c.JBCollectionID
                                             where mc.MenuID == menuId
                                             select new MenuLink
                                             {
                                                 Name = c.Name
                                                 ,
                                                 Image = c.CoverImage
                                                 ,
                                                 IsMenu = false
                                                 ,
                                                 Key = c.JBCollectionID
                                                 ,
                                                 ParentMenuID = -1
                                                 ,
                                                 HasImage = ((c.CoverImage == null || c.CoverImage == "") ? false :true)
                                                 ,
                                                 IsGame = false
                                             }).ToList();
                        }
                        else // non standard menu option
                        {
                            var query = (from g in db.Game 
                                             join e in db.Emulator on g.EmulatorID equals e.EmulatorID
                                             join ep in db.EmulatorPath on g.SnapshotPathID equals ep.EmulatorPathID into image
                                             from results in image.DefaultIfEmpty()
                                             join np in db.MameNPlayers on g.MameRomID equals np.MameRomID into nplayers
                                             from results2 in nplayers.DefaultIfEmpty()

                                            join ep2 in db.EmulatorPath on g.MoviePathID equals ep2.EmulatorPathID into video
                                            from results3 in video.DefaultIfEmpty()

                                             select new MenuLink
                                             {
                                                 Name = g.Name
                                                 ,
                                                 Description = g.Description
                                                 ,
                                                 Image = g.SnapshotFile != null ? results.Path + g.SnapshotSubPath + "\\" + g.SnapshotFile : host + "noimage.jpg"
                                                 ,
                                                 IsMenu = false
                                                 ,
                                                 Key = g.GameID
                                                 ,
                                                 ParentMenuID = -1
                                                 ,
                                                 LastPlayed = g.LastPlayed
                                                 ,
                                                 TotalTimePlayed = g.TotalTimePlayed
                                                 ,
                                                 NumberTimesPlayed = g.NumberTimesPlayed
                                                 ,
                                                 NPlayers = results2.NPlayers
                                                 ,
                                                 EmulatorImage = (e.ImageName == null || e.ImageName.Trim() == "" ? "" : host + e.ImageName)
                                                 ,
                                                 EmulatorName = e.Name
                                                 ,
                                                 Rating = g.Rating
                                                 ,
                                                 IsMame = (e.IsMame == 1 ? true : false)
                                                 ,
                                                 Video = g.MovieFile != null ? results3.Path + g.MovieSubPath + "\\" + g.MovieFile : null
                                                 ,
                                                 IsGame = true

                                             });

                            if (menuType == "top20")
                            {
                                itemMenuLinks = query.Where(x=> x.Rating != null).OrderByDescending(x => x.Rating).Take(20).ToList();
                            }
                            else if (menuType == "most20")
                            {
                                itemMenuLinks = query.Where(x => x.TotalTimePlayed != null).OrderByDescending(x => x.TotalTimePlayed).Take(20).ToList();
                            }
                            else if (menuType == "last20")
                            {
                                itemMenuLinks = query.Where(x => x.LastPlayed != null).OrderByDescending(x => x.LastPlayed).Take(20).ToList();
                            }

                        }
                        menuLinks.AddRange(itemMenuLinks);

                        //    
                    }


                }
            }

            menuLevel.Links = menuLinks;
            menuLevel.MenuPath = menuPath;
            menuLevel.ParentMenuId = parentMenuId;
            return menuLevel;
        }

        public static  GameInfo getGameInfo(int gameId)
        {
            GameInfo gameInfo = null;


            return gameInfo;
        }


        public static void saveGamePlayedStats(int gameId, int NumberOfMinutes)
        {
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {
                    Game g = db.Game.Where(x => x.GameID == gameId).Single();

                    g.LastPlayed = DateTime.Now;
                    g.TotalTimePlayed = (g.TotalTimePlayed??0) + NumberOfMinutes;
                    g.NumberTimesPlayed = (g.NumberTimesPlayed??0) + 1;

                    db.SubmitChanges();

                }
            }

        }

        public static void getGameExecutionInfo(int gameId, ref string executable, ref string arguments, ref bool IsMame)
        {
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {
                    var query = (from g in db.Game
                                 join e in db.Emulator on g.EmulatorID equals e.EmulatorID
                                 join ep in db.EmulatorPath on g.RomPathID equals ep.EmulatorPathID
                                 where g.GameID == gameId
                                 select new
                                 {
                                     e.Executable
                                     ,
                                     argumentTemplate = e.Arguments
                                     ,
                                     e.ConfigurationFile
                                     ,
                                     fullPath = ep.Path + g.RomSubPath + "\\" + g.RomFile
                                     ,
                                     romFile = g.RomFile
                                     ,
                                     romName = Path.GetFileNameWithoutExtension(g.RomFile)
                                     ,
                                     extension = Path.GetExtension(g.RomFile).Substring(1)
                                     ,
                                     romPath = ep.Path + g.RomSubPath
                                     ,
                                     IsGameMame = (bool)(e.IsMame==1?true:false)
                                 }).Single();

                    executable = query.Executable;

                    IsMame = query.IsGameMame;
                    // argument template stuff
                    /*
                     [rompath]
                     [romfile]
                     [romname]
                     [configfile]
                     * */


                    if (query.argumentTemplate != null && query.argumentTemplate.Trim() != "")
                    {

                        string argumentTemplate = query.argumentTemplate;

                        if (argumentTemplate.Contains("[path]"))
                            argumentTemplate = argumentTemplate.Replace("[path]", query.romPath);
                        if (argumentTemplate.Contains("[romfile]"))
                            argumentTemplate = argumentTemplate.Replace("[romfile]", query.romFile);
                        if (argumentTemplate.Contains("[rom]"))
                            argumentTemplate = argumentTemplate.Replace("[rom]", query.romName);
                        if (argumentTemplate.Contains("[ext]"))
                            argumentTemplate = argumentTemplate.Replace("[ext]", query.extension);
                        if (argumentTemplate.Contains("[configfile]"))
                            argumentTemplate = argumentTemplate.Replace("[configfile]", query.ConfigurationFile);

                        arguments = argumentTemplate;
                    }
                    else
                    {
                        // if no argument template supplied, just return the romname
                        arguments = query.romName;
                    }

                }
            }

        }


        public static void showHideElement(bool IsVisible, UIElement element)
        {

            if (IsVisible)
            {
                if (element.Visibility != System.Windows.Visibility.Visible)
                    element.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                if (element.Visibility != System.Windows.Visibility.Hidden)
                    element.Visibility = System.Windows.Visibility.Hidden;
            }
        }

        public static MyWindow getActiveWindow()
        {
            MyWindow activeWin = null;
            foreach (MyWindow win in App.Current.Windows)
            {
                if (win.IsActive)
                {
                    activeWin = win;
                    break;
                }
            }
            return activeWin;
        }

        public static void exitProgram()
        {
            string exitMethod = getConfig("Quit Action"); // quit/ shutdown/ suspend

            switch (exitMethod)
            {
                case "quit" :
                    App.Current.Shutdown();
                    break;

                case "shutdown" :
                    ExitWindowsEx(1, 0); // interop
                    break;

                case "hibernate":
                    System.Windows.Forms.Application.SetSuspendState(System.Windows.Forms.PowerState.Hibernate, true, true);
                    break;

                case "standby":
                    System.Windows.Forms.Application.SetSuspendState(System.Windows.Forms.PowerState.Suspend, true, true);
                    break;

            }
        }

        //public static void showErrorMessage(string errorMessage, System.Windows.Window parentWindow)
        //{

        //    ErrorMessage em = new ErrorMessage(errorMessage);
        //    em.Width = parentWindow.ActualWidth;
        //    em.Height = parentWindow.ActualHeight;
        //    em.Owner = parentWindow;
        //    em.ShowDialog();
        //}


        public static bool validatePassword(int menuId, string password)
        {

            bool isValidPassword = false;
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();
                using (LauncherDB db = new LauncherDB(ceConn))
                {
                    string actualPassword = (from m in db.Menu
                                 where m.MenuID == menuId
                                 select m.Password).SingleOrDefault().ToString();

                    if (password == actualPassword)
                        isValidPassword = true;
                }

            }
            return isValidPassword;
        }

        #region generate game details

        public static void generateDetails(int gameId, ref ListBox Viewer, ref TextBlock TitleBox, Window win)
        {
            bool useCache = false;
            // make sure cache folder exists
            string currentDir = getCurrentDir();
            string cacheDir = currentDir + (currentDir.EndsWith("\\") ? "" : "\\") + "DetailsCache\\";

            if (!Directory.Exists(cacheDir) && useCache)
                Directory.CreateDirectory(cacheDir);

            // cache name format is [game_id]_[sectionType].pak, eg 1_Overview


            List<FlowDocument> details = new List<FlowDocument>();

            //int defaultColumnWidth = 400;

            int? mameRomId = null;
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();
                using (LauncherDB db = new LauncherDB(ceConn))
                {
                    mameRomId = (from g in db.Game
                                 where g.GameID == gameId
                                 select g.MameRomID).SingleOrDefault();
                }

            }

            string gameName = "";
            if (mameRomId != null)
            {
                string 
                      overviewCacheFile = cacheDir + gameId.ToString() + "_Overview.xaml"
                    , commandsCacheFile = cacheDir + gameId.ToString() + "_Commands.xaml"
                    , historyCacheFile = cacheDir + gameId.ToString() + "_History.xaml"
                    , controlsCacheFile = cacheDir + gameId.ToString() + "_Controls.xaml";



                // overview
                FlowDocument overViewDoc = null;
                if (useCache && File.Exists(overviewCacheFile))
                {
                    loadFlowDocument(ref overViewDoc, overviewCacheFile);
                }
                else
                {
                    Section overviewSection = getOverview((int)mameRomId, ref gameName);
                    if (overviewSection != null)
                    {
                        overViewDoc = GetNewDoc("Overview", overviewSection, false, win);
                        if (useCache && overViewDoc != null)
                            saveFlowDocument(overViewDoc, overviewCacheFile);
                    }
                }
                if(overViewDoc != null)
                    details.Add(overViewDoc);

                // commands
                FlowDocument commandsDoc = null;
                if (useCache && File.Exists(commandsCacheFile))
                {
                    loadFlowDocument(ref commandsDoc, commandsCacheFile);
                }
                else
                {
                    Section commandsSection = getCommands((int)mameRomId);
                    if (commandsSection != null)
                    {
                        commandsDoc = GetNewDoc("Commands", commandsSection, true, win);
                        if (useCache && commandsDoc != null)
                            saveFlowDocument(commandsDoc, commandsCacheFile);
                    }
                }
                if (commandsDoc != null)
                    details.Add(commandsDoc);

                // history
                FlowDocument historyDoc = null;
                if (useCache && File.Exists(historyCacheFile))
                {
                    loadFlowDocument(ref historyDoc, historyCacheFile);
                }
                else
                {
                    Section historySection = getHistory((int)mameRomId);
                    if (historySection != null)
                    {
                        historyDoc = GetNewDoc("History", historySection, true, win);
                        if (useCache && historyDoc != null)
                            saveFlowDocument(historyDoc, historyCacheFile);
                    }
                }
                if (historyDoc != null)
                    details.Add(historyDoc);


                // controls
                FlowDocument controlsDoc = null;
                if (useCache && File.Exists(controlsCacheFile))
                {
                    loadFlowDocument(ref controlsDoc, controlsCacheFile);
                }
                else
                {
                    Section controlsSection = getControlPanel(1, gameId);
                    if (controlsSection != null)
                    {
                        controlsDoc = GetNewDoc("Controls", controlsSection, true, win);
                        if (useCache && historyDoc != null)
                            saveFlowDocument(controlsDoc, controlsCacheFile);
                    }
                }
                if (controlsDoc != null)
                    details.Add(controlsDoc);

            }
            TitleBox.Text = gameName;

            //details.Add(new DetailSection("MAIN", doc));
            Viewer.ItemsSource = details;

            if (details.Count > 0)
            {
                Viewer.SelectedIndex = 0;
                Viewer.Focus();
            }
            //docReader.Document = doc;

        }

        private static bool saveFlowDocument(FlowDocument doc, string fileName)
        {
            bool isSuccess = false;
            using (FileStream fs = File.Create(fileName)) // FileStream FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            {
                TextRange textRange = new TextRange(doc.ContentStart, doc.ContentEnd);
                textRange.Save(fs, DataFormats.Xaml);
                isSuccess = true;
            }
            return isSuccess;
        }

        private static bool loadFlowDocument(ref FlowDocument doc, string fileName)
        {
            bool isSuccess = false;
            doc = new FlowDocument();
            using (FileStream fs = File.OpenRead(fileName)) // FileStream FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            {
                TextRange range = new TextRange(doc.ContentStart, doc.ContentEnd);
                range.Load(fs, DataFormats.Xaml);  

                isSuccess = true;
            }
            return isSuccess;
        }

        private static Section getHistory(int mameRomId)
        {
            Section s = null;
            try
            {
                string history = null;

                using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
                {

                    ceConn.Open();
                    using (LauncherDB db = new LauncherDB(ceConn))
                    {
                        history = (from x in db.MameHistory
                                   where x.MameRomID == mameRomId
                                   select x.History).SingleOrDefault();
                    }

                }

                if (history != null)
                {
                    history = history.Replace("\r\n\r\n", "\r\n");

                    s = GetNewSection();

                    Paragraph p = new Paragraph();

                    p.Inlines.Add(history);
                    s.Blocks.Add(p);


                }
            }
            catch (Exception)
            {
                return null;
            }


            return s;
        }

        private static Section getControlPanel(int controlPanelId, int gameId)
        {

            Section s = null;

            try
            {
                using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
                {

                    ceConn.Open();
                    using (LauncherDB db = new LauncherDB(ceConn))
                    {


                        // void getControlPanelCanvas(int controlPanelId, int gameId )
                        //{
                        int controlPanelAssignmentId = -1;

                        // get the game record
                        var record = (
                            from g in db.Game
                            join e in db.Emulator on g.EmulatorID equals e.EmulatorID
                            join mr in db.MameRom on g.MameRomID equals mr.MameRomID into mamerom
                            where g.GameID == gameId
                            from x in mamerom.DefaultIfEmpty()
                            select new
                            {
                                isMame = ((int)e.IsMame == 1 ? true : false)
                                ,
                                emulatorId = e.EmulatorID
                                ,
                                mameRom = x.RomName
                                ,
                                mameRomId = x.MameRomID
                            }
                                ).SingleOrDefault();

                        string driverName = "";

                        if (record.isMame)
                        {
                            driverName = (from mr in db.MameRom
                                          join mrb in db.MameRomBios on mr.MameRomID equals mrb.MameRomID
                                          join mr2 in db.MameRom on mrb.BiosMameRomID equals mr2.MameRomID
                                          where mr.MameRomID == record.mameRomId
                                          select mr2.RomName).SingleOrDefault();
                        }

                        // control panel details
                        var controlPanel = (from x in db.ControlPanel
                                            where x.ControlPanelID == controlPanelId
                                            select new
                                            {
                                                x.Height
                                                ,
                                                x.Width
                                                ,
                                                x.PanelName
                                            }).SingleOrDefault();

                        if (record.isMame)
                        {
                            // if its mame - use the controls table

                            // check if rom assignment exists..
                            var check = (from x in db.ControlPanelAssignment
                                         where x.EmulatorID == record.emulatorId
                                         && x.SystemTag == record.mameRom
                                         && x.ControlPanelID == controlPanelId
                                         select x).SingleOrDefault();

                            if (check != null)
                            {
                                controlPanelAssignmentId = check.ControlPanelAssignmentID;
                            }
                            else
                            {
                                // check if driver assignment exists
                                check = (from x in db.ControlPanelAssignment
                                         where x.EmulatorID == record.emulatorId
                                         && x.SystemTag == driverName
                                         && x.ControlPanelID == controlPanelId
                                         select x).SingleOrDefault();

                                // check if default exists..
                                if (check != null)
                                {
                                    controlPanelAssignmentId = check.ControlPanelAssignmentID;
                                }
                                else
                                {

                                    // check if driver assignment exists
                                    check = (from x in db.ControlPanelAssignment
                                             where x.EmulatorID == record.emulatorId
                                             && x.SystemTag == "default"
                                             && x.ControlPanelID == controlPanelId
                                             select x).SingleOrDefault();

                                    if (check != null)
                                    {
                                        controlPanelAssignmentId = check.ControlPanelAssignmentID;
                                    }
                                }
                            }

                        }
                        else
                        {
                            // other emulators just have default..
                            // check if driver assignment exists
                            var check = (from x in db.ControlPanelAssignment
                                         where x.EmulatorID == record.emulatorId
                                         && x.SystemTag == "default"
                                         && x.ControlPanelID == controlPanelId
                                         select x).SingleOrDefault();

                            if (check != null)
                                controlPanelAssignmentId = check.ControlPanelAssignmentID;
                        }

                        if (controlPanelAssignmentId > 0)
                        {
                            // grab appropriate labels from db....
                            Dictionary<string, List<string>> labels, labelsCopy;

                            if (record.isMame)
                            {
                                labels =
                                    (from x in db.MamePlayer
                                     join y in db.MamePlayerLabel on x.MamePlayerID equals y.MamePlayerID
                                     join z in db.MameLabel on y.MameLabelID equals z.MameLabelID
                                     where x.MameRomID == record.mameRomId
                                     select new { Assignment = z.Name, Label = z.Value, z.Color }
                                    ).ToDictionary(a => a.Assignment, b => new List<string> { b.Label, b.Color });


                                // check if mirrored - to copy to other player(s)
                                bool IsMirrored = false;
                                int numPlayers = 1;
                                
                                var MameControlCheck =   (from mci in db.MameControlsInfo
                                                     where mci.MameRomID == record.mameRomId
                                                     select new {
                                                         IsMirrored = ((int?)mci.Mirrored == 1 ? true : false)
                                                         ,
                                                         NumPlayers = ((int?)mci.NumPlayers == null ? 1 : (int)mci.NumPlayers)
                                                }).SingleOrDefault();

                                if (MameControlCheck != null)
                                {
                                    IsMirrored = MameControlCheck.IsMirrored;
                                    numPlayers = MameControlCheck.NumPlayers;
                                }

                                if (IsMirrored && numPlayers > 1)
                                {
                                    labelsCopy = new Dictionary<string, List<string>>();
                                    foreach (KeyValuePair<string, List<string>> existingLabel in labels)
                                    {
                                        labelsCopy.Add(existingLabel.Key, existingLabel.Value);
                                    }

                                    
                                    foreach (KeyValuePair<string, List<string>> existingLabel in labelsCopy)
                                    {
        

                                        string existingAssignment = existingLabel.Key;
                                        List<string> existingLabelValue = existingLabel.Value;

                                        if (existingAssignment.StartsWith("P1_"))
                                        {
                                            for (int playerNum = 2; playerNum <= numPlayers; playerNum++)
                                            {
                                                string newAssignment = existingAssignment.Replace("P1_", "P" + playerNum.ToString() + "_");
                                                labels.Add(newAssignment, existingLabelValue);
                                            }
                                        }
                                    }

                                    labelsCopy.Clear();
                                }

                                // ******* we also need to add the mame UI_ assignments, if they exist *************
                                string labelFile = getCurrentDir() + "\\DataFiles\\MameUILabels.xml";
                                var labelFileDoc = XElement.Load(labelFile);

                                var labelLookup = (from k in labelFileDoc.Descendants("label")
                                                     select new
                                                     {
                                                         tag = (string)k.Attribute("tag")
                                                         ,
                                                         text = (string)k.Attribute("text")
                                                     }).ToDictionary(a => a.tag, b => new List<string> { b.text, null});

                                foreach (KeyValuePair<string, List<string>> label in labelLookup)
                                {
                                    labels.Add(label.Key,label.Value);
                                }
                            }
                            else
                            {
                                labels = new Dictionary<string, List<string>>();
                            }

                            var controlItems = (
                                from cp in db.ControlPanel
                                join cpi in db.ControlPanelItem on cp.ControlPanelID equals cpi.ControlPanelID
                                where cp.ControlPanelID == controlPanelId
                                select new
                                {
                                    cpi.ItemType
                                    ,
                                    cpi.PosX
                                    ,
                                    cpi.PosY
                                    ,
                                    cpi.Color
                                    ,
                                    cpi.LabelPosition
                                    ,
                                    inputs =
                                      (
                                      from cpii in db.ControlPanelItemInput
                                      join cpia in db.ControlPanelInputAssignment on cpii.ControlPanelItemInputID equals cpia.ControlPanelItemInputID
                                      where cpii.ControlPanelItemID == cpi.ControlPanelItemID
                                      && cpia.ControlPanelAssignmentID == controlPanelAssignmentId
                                      select new
                                      {
                                          cpii.InputType
                                          ,
                                          cpii.KeyCode
                                          ,
                                          cpia.AssignmentTag
                                          ,
                                          Label = (labels.ContainsKey(cpia.AssignmentTag) ? labels[cpia.AssignmentTag][0] : null)
                                          ,
                                          Color = (labels.ContainsKey(cpia.AssignmentTag) ? labels[cpia.AssignmentTag][1] : null)
                                      }
                                      ).ToList()

                                }).ToList();

                            //controlItems.Dump();

                            // generate IMage

                            Canvas c = new Canvas()
                            {
                                Height = controlPanel.Height
                                ,
                                Width = controlPanel.Width
                            };

                            BrushConverter conv = new BrushConverter();
                            Size availSize = new Size(1000, 1000);

                            foreach (var controlItem in controlItems)
                            {
                                SolidColorBrush brush = conv.ConvertFromString(controlItem.Color) as SolidColorBrush;


                                Thumb t = new Thumb();
                                t.SnapsToDevicePixels = true;
                                switch (controlItem.ItemType)
                                {
                                    case "Joystick":
                                        t.Style = Application.Current.Resources["myJoystick"] as Style;
                                        break;
                                    case "Button":
                                        t.Style = Application.Current.Resources["myButton"] as Style;
                                        break;
                                    case "Trackball":

                                        break;
                                }

                                t.Background = brush;


                                t.Measure(availSize);
                                Size thumbSize = t.DesiredSize;
                                int buffer = 10;


                                // add labels
                                foreach (var input in controlItem.inputs)
                                {
                                    if (input.Label != null)
                                    {
                                        TextBlock tb = new TextBlock()
                                        {
                                            Text = input.Label
                                            ,
                                            TextWrapping = TextWrapping.NoWrap
                                            ,
                                            TextAlignment = TextAlignment.Center
                                            ,
                                            SnapsToDevicePixels = true
                                            ,
                                            FontSize = 10
                                            ,
                                            FontWeight = FontWeights.Bold
                                        };
                                        tb.Measure(availSize);

                                        c.Children.Add(tb);
                                        Size sz = tb.DesiredSize;

                                        int textHeight = (int)sz.Height; // (int)tb.ActualHeight;
                                        int textWidth = (int)sz.Width; // (int)tb.ActualWidth;

                                        // calculate positions
                                        int centerTopXPos = controlItem.PosX + (int)(thumbSize.Width / 2); // center of thumb
                                        int actualTopYPos = controlItem.PosY;

                                        int aboveBelowXPos = centerTopXPos - (textWidth / 2);
                                        int aboveYPos = actualTopYPos - buffer - (textHeight / 2);
                                        int belowYPos = actualTopYPos + (int)thumbSize.Height + buffer - (textHeight / 2);

                                        int leftXPos = controlItem.PosX - textWidth - buffer;
                                        int leftRightYPos = controlItem.PosY + (int)(thumbSize.Height / 2) - (textHeight / 2);

                                        int rightXPos = controlItem.PosX + (int)thumbSize.Width + buffer;


                                        string labelPos = "";

                                        switch (input.InputType)
                                        {
                                            case "ACTION":
                                                labelPos = controlItem.LabelPosition;
                                                break;
                                            case "LEFT":
                                                labelPos = "Left";
                                                break;
                                            case "RIGHT":
                                                labelPos = "Right";
                                                break;
                                            case "UP":
                                                labelPos = "Above";
                                                break;
                                            case "DOWN":
                                                labelPos = "Below";
                                                break;
                                        }

                                        switch (labelPos)
                                        {

                                            case "Above":
                                                Canvas.SetLeft(tb, aboveBelowXPos);
                                                Canvas.SetTop(tb, aboveYPos);
                                                break;
                                            case "Below":
                                                Canvas.SetLeft(tb, aboveBelowXPos);
                                                Canvas.SetTop(tb, belowYPos);
                                                break;
                                            case "Left":
                                                Canvas.SetLeft(tb, leftXPos);
                                                Canvas.SetTop(tb, leftRightYPos);
                                                break;
                                            case "Right":
                                                Canvas.SetLeft(tb, rightXPos);
                                                Canvas.SetTop(tb, leftRightYPos);
                                                break;

                                        }




                                        Canvas.SetZIndex(tb, 99);
                                    }

                                    if (input.Color != null)
                                    {
                                        //ColorConverter cc = new ColorConverter();
                                        Color col = (Color)ColorConverter.ConvertFromString(input.Color);
                                        t.Effect = getGlowEffect(col);
                                    }
                                }

                                c.Children.Add(t);
                                Canvas.SetLeft(t, controlItem.PosX);
                                Canvas.SetTop(t, controlItem.PosY);
                                Canvas.SetZIndex(t, 1);

                            }

                            s = GetNewSection();

                            Paragraph p = new Paragraph();

                            // put it in a viewbox so it stretches nicely
                            Viewbox vb = new Viewbox()
                            {
                                Stretch = Stretch.Uniform
                                 ,
                                MaxHeight = 600
                            };
                            vb.Child = c;
                            p.Inlines.Add(vb);
                            s.Blocks.Add(p);


                        }
                    }


                    //}
                    // marry up labels with control panel assignment.....
                    ;

                    //}
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            return s;
        }

        private static Section getCommands(int mameRomId)
        {

           // double imageHeight = fontSize * 1.2;

            Section s = null;

            try
            {
                // get list of images as a reference
                // note: replace __ with _, due to windows thinking _T and _t are the same (case insensitive)
                Dictionary<string, string> images = (from x in System.IO.Directory.GetFiles("Media\\CommandDat")
                                                     select new
                                                     {
                                                         path = x.ToString()
                                                         ,
                                                         name = System.IO.Path.GetFileNameWithoutExtension(x.ToString()).Replace("__", "_")
                                                     }
                                                     ).ToDictionary(a => a.name, b => b.path);

                using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
                {

                    ceConn.Open();
                    using (LauncherDB db = new LauncherDB(ceConn))
                    {
                        var commandList = (
                                        from mrc in db.MameRomCommand
                                        join mc in db.MameCommand on mrc.MameCommandSetID equals mc.MameCommandSetID
                                        where mrc.MameRomID == mameRomId
                                        orderby mc.SortOrder
                                        select new { mc.Heading, mc.Content }
                                       ).ToList();

                        if (commandList != null && commandList.Count > 0)
                        {
                            s = GetNewSection();

                            foreach (var command in commandList)
                            {
                                Paragraph p = new Paragraph();

                                Bold b = new Bold();
                                //b.FontSize = fontSize;
                                b.Inlines.Add(command.Heading + "\n");

                                p.Inlines.Add(b);



                                string commandString = command.Content;
                                // fix up string / images
                                List<CommandItem> commItems = new List<CommandItem>();

                                // 1st parse, identify positions of special items
                                bool containsItems = false;
                                foreach (KeyValuePair<string, string> item in images)
                                {
                                    if (commandString.Contains(item.Key))
                                    {
                                        int startIndex = 0;
                                        int newIndex = 0;
                                        while (newIndex >= 0)
                                        {
                                            newIndex = commandString.IndexOf(item.Key, startIndex);
                                            if (newIndex >= 0)
                                            {
                                                commItems.Add(new CommandItem(item.Key, newIndex));
                                            }
                                            startIndex = newIndex + 1;
                                        }

                                        if (!containsItems)
                                            containsItems = true;

                                    }
                                }

                                if (containsItems)
                                {
                                    commItems.Sort();

                                    // now process string, with knowledge of location of items
                                    int currPos = 0;
                                    string chunk = "";
                                    int length = 0;
                                    foreach (CommandItem commItem in commItems)
                                    {
                                        // grab string before item
                                        if (commItem.Position > 0)
                                        {
                                            length = commItem.Position - currPos;
                                            chunk = commandString.Substring(currPos, length);
                                            p.Inlines.Add(chunk);

                                        }

                                        // now add item
                                        Image i = new Image();
                                        //i.Width = imageHeight;
                                        //i.Height = imageHeight;
                                        Uri uriSource = new Uri(images[commItem.Item], UriKind.Relative);
                                        i.Source = new BitmapImage(uriSource);

                                        //Viewbox vb = new Viewbox();
                                        //vb.Child = i;
                                        //vb.Style = (Style)win.FindResource("vbImageContainer");

                                        //Binding binding = new Binding();
                                        //binding.ElementName = "Viewer";
                                        //binding.Path = 

                                        p.Inlines.Add(i); //vb

                                        currPos = commItem.Position + commItem.ItemLength();

                                    }

                                    // add missing end bit
                                    if (currPos < commandString.Length)
                                    {
                                        p.Inlines.Add(commandString.Substring(currPos));
                                    }

                                    // end fix up string
                                }
                                else
                                {

                                    p.Inlines.Add(commandString);
                                }
                                s.Blocks.Add(p);
                            }
                        }



                    }
                }
            }
            catch (Exception)
            {
                return null;
            }
            return s;

        }

        private static Section getOverview(int mameRomID, ref string gameName)
        {
            Section s;

            try
            {
                using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
                {

                    ceConn.Open();
                    using (LauncherDB db = new LauncherDB(ceConn))
                    {
                        var mameOverview = (
                                    from mr in db.MameRom
                                    join mci in db.MameControlsInfo on mr.MameRomID equals mci.MameRomID
                                    join mnp in db.MameNPlayers on mr.MameRomID equals mnp.MameRomID
                                    where mr.MameRomID == mameRomID
                                    select new
                                    {
                                        mr.GameName
                                        ,
                                        mr.Year
                                        ,
                                        mr.SourceFile
                                        ,
                                        mr.CloneOf
                                        ,
                                        mr.DriverStatus
                                        ,
                                        mr.Manufacturer
                                        ,
                                        mci.MiscDetails
                                        ,
                                        mnp.NPlayers
                                        ,
                                        mr.RomName
                                    }
                                    ).SingleOrDefault();








                        s = GetNewSection();


                        Paragraph p = new Paragraph();

                        p.Inlines.Add("Name : " + mameOverview.GameName + "\n");
                        p.Inlines.Add("Manufacturer : " + mameOverview.Manufacturer + "\n");
                        p.Inlines.Add("Year : " + mameOverview.Year + "\n");
                        p.Inlines.Add("Misc Details : " + mameOverview.MiscDetails + "\n");

                        s.Blocks.Add(p);

                        gameName = mameOverview.GameName;
                        //tbManufacturerYear.Text = mameOverview.Manufacturer + " (" + mameOverview.Year + ")";
                        //tbMiscDetails.Text = mameOverview.MiscDetails;
                    }

                }
            }
            catch (Exception)
            {
                return null;
            }
            return s;
        }

        private static Section GetNewSection()
        {
            Section s = new Section()
            {
                Foreground = new SolidColorBrush(Colors.White)
                    ,
                Background = new SolidColorBrush(Colors.Transparent)
            };
            return s;
        }

        private static FlowDocument GetNewDoc(string heading, Section section, bool split, Window win)
        {
            FlowDocument doc = new FlowDocument()
            {
                Style = (Style)win.FindResource((split ? "FlowDocumentSplit" : "FlowDocumentNormal"))
            };



            Paragraph head = new Paragraph();
            Bold bh = new Bold();
            //bh.FontSize = fontSize + 2;
            bh.Inlines.Add(heading);
            head.Inlines.Add(bh);
            //doc.Blocks.Add(head);

            section.Blocks.InsertBefore(section.Blocks.FirstBlock, head);

            doc.Blocks.Add(section);
            return doc;
        }

        private static Effect getGlowEffect(Color glowColor)
        {
            DropShadowEffect effect = new DropShadowEffect();
            effect.ShadowDepth = 0;
            effect.BlurRadius = 15;
            effect.Color = glowColor;
            return effect;
        }


        public static StackPanel generateNPlayersImage(string nplayers)
        {

            StackPanel sp = new StackPanel()
            {
                Orientation = Orientation.Horizontal
            };
            //sp.Children.Add(new Label() { Content="TEST", FontSize=30 });
            //sp.Children.Add(getImage("player"));
            //return sp;
            // distinct values in DB
            //1P
            //2P alt
            //2P sim
            //3P alt
            //3P sim
            //4P alt
            //4P alt / 2P sim
            //4P sim
            //6P alt
            //6P sim
            //8P alt / 2P sim
            //8P sim


            // 0. ignore anything with ?? in it, and BIOS
            if (nplayers.Contains("?") || nplayers == "BIOS")
                return sp;


            // 1. split up based on '/'
            string[] entries = nplayers.Split('/');




            // 2. for each entry in array, grab 'xP' -> number of players, if alt or sim use different indicator... (alt arrow, sim plus)


            foreach (string entry in entries)
            {
                string[] arrTemp = entry.Split(' ');

                int number = Int16.Parse(arrTemp[0].Substring(0, arrTemp[0].Length - 1)); // eg 1
                string type = arrTemp[1]; // eg sim


                for (int i = 1; i <= number; i++)
                {
                    sp.Children.Add(ClientLib.getImageFromMedia("player"));
                    if (i != number)
                    {
                        sp.Children.Add(ClientLib.getImageFromMedia(type));
                    }
                }

            }


            return sp;
        }

        #endregion



        public static void getTrackInfo(int trackid, ref string Artist, ref string Title)
        {
            
            using (SqlCeConnection ceConn = new SqlCeConnection(getConnectionString()))
            {

                ceConn.Open();

                using (LauncherDB db = new LauncherDB(ceConn)) // linq
                {

                    var trackInfo = (from x in db.JBTrack
                             where x.JBTrackID == trackid
                             select new {x.Name, x.Artists }).SingleOrDefault();

                    Artist = trackInfo.Artists;
                    Title = trackInfo.Name;
                }
            }
        }


    }




    public class CommandItem : IComparable
    {
        public string Item { get; set; }
        public int Position { get; set; }

        public CommandItem(string item, int pos)
        {
            this.Item = item;
            this.Position = pos;
        }

        public int ItemLength()
        {
            return Item.Length;
        }

        public int CompareTo(object obj)
        {
            CommandItem myObject = (CommandItem)obj;
            return this.Position.CompareTo(myObject.Position);
        }

    }

    public   class MenuLevel
    {
        public List<string> MenuPath { get; set; }

        public int ParentMenuId { get; set; }

        public List<MenuLink> Links { get; set; }

        public int Level { get; set; }
    }

    public  class MenuLink
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsMenu { get; set; } // true if menu, otherwise assume game
        public string Image { get; set; }
        public string Video { get; set; }
        public int Key { get; set; } // key value in database (menuId or gameId)
        public int ParentMenuID { get; set; }
        public bool HasImage { get; set; }

        public bool IsMame {get; set;}
        public DateTime? LastPlayed {get;set;}
        public int? TotalTimePlayed {get;set;}
        public int? NumberTimesPlayed { get; set; }
        public string NPlayers { get; set; }

        public bool SecuredLevel { get; set; }
        public string SecuredPassword { get; set; }

        public int? Rating { get; set; }

        public string EmulatorImage { get; set; }
        public string EmulatorName { get; set; }
        public bool IsGame { get; set; }
    }

    public  class GameInfo
    {
        public string Name { get; set; }
        public string Description { get; set; }

        // return more info - like manufacturer, moves, history, etc

    }
}
